#ifndef GAME_H
#define GAME_H

#include "openglpaintingarea.h"
#include <QThread>

class QThread;
class Canvas;
class element;

//class GameHandle {
//public:
//    GameHandle() = default;
//};

class Game : public QThread {
    Q_OBJECT
public:
    using gt = ctl_types::gaming_tag;
    Game() = default;
    virtual ~Game() = default;
    void setCanvas(Canvas* ca);
    Canvas* getCanvas();
    void setGameState(const gt gs);
    const gt getGameState() const;
    virtual void newGame() = 0;
    virtual void afterGameOver() = 0;
    virtual void keyPress(QKeyEvent *event) = 0;
    virtual void keyRelease(QKeyEvent *event) = 0;
    virtual void updateCanvas() = 0;
signals:
    void flush();
private:
    Canvas * canvas;
    gt game_state;
};

class RussianBlock : public Game {
public:
    using bgt = rb_types::generator_type;
    RussianBlock() = default;
    ~RussianBlock();
    RussianBlock(const RussianBlock& rb) = delete; //can not use rb.get functions
    void Create(Canvas * ca);
    void setBlockGenerator(const bgt gt);
    const bgt getBlockGenerator() const;
    virtual void newGame();
    virtual void afterGameOver();
    virtual void keyPress(QKeyEvent *event);
    virtual void keyRelease(QKeyEvent *event);
    virtual void updateCanvas();

    inline bool checkPath();
    inline void setNextBlock();
    inline void eliminate();

    void run(); // start(): begin this function in a new thread
                // terminate(): stop(finish) the thread
                // end(): thread may be terminated at any point(it could be dangerous but cost nothing here)

private:
    unsigned int speed_slot;
    rb_types::BlockGenerator * block_generator;
    rb_types::block_type new_block;
    unsigned int block_rotation; // 0~3
    std::vector<std::vector<rb_types::Point> > block_shape;
    std::vector<std::vector<bool> > buffer; //存储块未落低前无此块的画布状态
    int vertical = 20;
    int horizontal = 0; // min value : 0; max value : board_width(10)
};

#endif // GAME_H
